# encoding:utf8
"""
Module Description: 角色资源数值和元宝的管理
Date:2016/11/02
Anchor:Bai Jin Ping
"""
import zope.component

from pyshare.bll import events
from pyshare.const.enums.payment import FakeFlag
from pyshare.const.enums.power_fund import LimitFundType
from pyshare.dal.repository_impl import ResourcesRepository
from pyshare.const.lang.tips_info import TipsInfo
from pyshare.const.enums.activity import ActivityType
from pyshare.const.enums.item import ItemType
from pyshare.distributed.role_lock import RoleLock
from pyshare.bll.errors import ResourcesError
from pyshare.framework.logproxy.log_proxy import GameLogProxy


# 资源名称要和保存资源的字段名称相同
# 大清2：银两，粮食，士兵，元宝, 悟性值, 装备强化普通/高级材料
res_name_type_mapping = {
    'Silvers': ItemType.Silver,
    'Grains': ItemType.Food,
    'Soldiers': ItemType.Soldier,
    'GameGold': ItemType.GameGold,
    'Perceptions': ItemType.Perception,
    'EquipmentStuffNormal': ItemType.EquipmentStuffNormal,
    'EquipmentStuffAdvance': ItemType.EquipmentStuffAdvance,
}
res_type_name_mapping = {res_type: res_name for res_name, res_type in res_name_type_mapping.iteritems()}

res_not_enough_str = {ItemType.Silver: TipsInfo.ResourceKeys.silversNotEnough, ItemType.Food: TipsInfo.ResourceKeys.grainsNotEnough,
                      ItemType.Soldier: TipsInfo.ResourceKeys.soldiersNotEnough, ItemType.GameGold: TipsInfo.ResourceKeys.GoldsNotEnough,
                      ItemType.Perception: TipsInfo.ResourceKeys.PerceptionNotEnough, ItemType.EquipmentStuffNormal: TipsInfo.Equipment.EquipmentStuffNormalNotEnough,
                      ItemType.EquipmentStuffAdvance: TipsInfo.Equipment.EquipmentStuffAdvanceNotEnough}

# 资源对应活动类型
res_type_to_activity_type = {ItemType.Silver: ActivityType.CostSilvers,
                             ItemType.Food: ActivityType.CostFoods,
                             ItemType.Soldier: ActivityType.CostSoldiers,
                             ItemType.GameGold: ActivityType.CostGameGold,
                             ItemType.Perception: ActivityType.CrossNumerology
                             }


free_gold_log_field_name = 'free_gold'
pay_gold_log_field_name = 'pay_gold'


class ResManager(object):
    """
    资源管理类
    """

    def __init__(self, rid):
        if isinstance(rid, str) or isinstance(rid, unicode):
            self._dynamic_data = ResourcesRepository.get_by_rid(rid)
        else:
            self._dynamic_data = rid

        # 元宝相关控制参数
        # 初始元宝
        self._init_game_gold = self._dynamic_data.game_gold
        # 初始充值元宝
        self._init_recharge_game_gold = self._dynamic_data.recharge_game_gold
        # 优先扣完充值元宝之后，需要扣除的赠送元宝数
        self._need_reduce_free_gamegold = 0

    #########################
    # 查询&判断
    #########################
    def get_silvers(self):
        """获取当前银两"""
        return self._dynamic_data.silvers

    def get_grains(self):
        """获取当前粮食"""
        return self._dynamic_data.grains

    def get_soldiers(self):
        """获取当前士兵数量"""
        return self._dynamic_data.soldiers

    def get_gamegold(self):
        """获取当前元宝"""
        return self._dynamic_data.game_gold

    def _get_free_gamegold(self):
        """获取赠送元宝值"""
        return self._dynamic_data.game_gold - self._dynamic_data.recharge_game_gold

    def _get_recharge_gamegold(self):
        """获取充值元宝值"""
        return self._dynamic_data.recharge_game_gold

    def get_perceptions(self):
        """获取当前悟性值"""
        return self._dynamic_data.perceptions

    def get_equipmentstuffnormal(self):
        """获取当前装备普通强化材料"""
        return self._dynamic_data.equipment_stuff_normal

    def get_equipmentstuffadvance(self):
        """获取当前装备高级强化材料"""
        return self._dynamic_data.equipment_stuff_advance

    def check_meet_need_require_resource(self, need_silver=None, need_food=None):
        """
        是否达到相应的资源需求
        :param need_silver: 所需银两
        :param need_food: 所需粮食
        :return:
        """
        if need_silver is not None and self._dynamic_data.silvers < need_silver:
            return False
        if need_food is not None and self._dynamic_data.grains < need_food:
            return False
        return True

    def check_require_resource_by_type(self, r_type, num):
        """
        根据资源类型检查是否有足够数量
        :param r_type:
        :param num:
        :return:
        """
        res_name = self.get_res_name_by_type(r_type)
        if getattr(self._dynamic_data, res_name) < num:
            return False
        return True

    @staticmethod
    def get_res_name_by_type(res_type):
        '''
        根据资源类型id获取资源名称
        :param res_type:
        :return:
        '''
        assert res_type in res_type_name_mapping
        return res_type_name_mapping.get(res_type)

    @staticmethod
    def get_res_type_by_name(res_name):
        """
        根据资源名称获取资源类型
        :param res_name:资源名称: Silvers, Grains
        """
        res_name = res_name.capitalize()
        return res_name_type_mapping.get(res_name)

    def get_res_by_type(self, res_type):
        """
        根据资源类型获取资源数值
        :param res_type:
        :return:
        """
        assert res_type in res_type_name_mapping
        func_name = 'get_%s' % res_type_name_mapping[res_type].lower()
        return getattr(self, func_name)()

    def get_res_by_name(self, res_name):
        """
        根据资源名称获取指定资源数值
        :param res_name:资源名称
        :return:计算精度后的动态资源数值
        """
        assert res_name in res_name_type_mapping
        func_name = 'get_%s' % res_name.lower()
        return getattr(self, func_name)()

    #########################
    # 修改
    #########################
    def _update_silvers(self, delta_silver, negative=False):
        """
        更新银两值
        """
        num = self._dynamic_data.silvers + delta_silver
        if not negative and num < 0:
            raise ResourcesError('invalid silvers: {0}'.format(num))
        self._dynamic_data.silvers = max(num, 0) if not negative else num

    def _update_grains(self, delta_grains, negative=False):
        """
        更新粮食值
        """
        num = self._dynamic_data.grains + delta_grains
        if not negative and num < 0:
            raise ResourcesError('invalid grains: {0}'.format(num))
        self._dynamic_data.grains = max(num, 0) if not negative else num

    def _update_soldiers(self, delta_soldiers, negative=False):
        """
        更新兵力
        """
        num = self._dynamic_data.soldiers + delta_soldiers
        if not negative and num < 0:
            raise ResourcesError('invalid soldiers: {0}'.format(num))
        self._dynamic_data.soldiers = max(num, 0) if not negative else num

    def _update_perceptions(self, delta_perceptions, negative=False):
        """
        更新悟性值
        """
        num = self._dynamic_data.perceptions + delta_perceptions
        if not negative and num < 0:
            raise ResourcesError('invalid perceptions: {0}'.format(num))
        self._dynamic_data.perceptions = max(num, 0) if not negative else num

    def _update_equipmentstuffnormal(self, delta_normal_stuff, negative=False):
        """
        更新装备强化普通材料
        """
        num = self._dynamic_data.equipment_stuff_normal + delta_normal_stuff
        if not negative and num < 0:
            raise ResourcesError('invalid equipment_stuff_normal: {0}'.format(num))
        self._dynamic_data.equipment_stuff_normal = max(num, 0) if not negative else num

    def _update_equipmentstuffadvance(self, delta_advance_stuff, negative=False):
        """
        更新装备强化普通材料
        """
        num = self._dynamic_data.equipment_stuff_advance + delta_advance_stuff
        if not negative and num < 0:
            raise ResourcesError('invalid equipment_stuff_advance: {0}'.format(num))
        self._dynamic_data.equipment_stuff_advance = max(num, 0) if not negative else num

    def _update_resource_by_type(self, res_type, num, is_recharge=False, negative=False):
        """根据资源类型，更新资源"""
        assert res_type in res_type_name_mapping

        # 普通资源：银粮兵,悟性值
        if res_type in (ItemType.Food, ItemType.Soldier, ItemType.Silver, ItemType.Perception,
                        ItemType.EquipmentStuffNormal, ItemType.EquipmentStuffAdvance):
            func_name = '_update_%s' % res_type_name_mapping[res_type].lower()
            getattr(self, func_name)(num, negative=negative)

        # 元宝
        elif res_type == ItemType.GameGold:
            if num < 0:
                self._reduce_game_gold(-num, negative=negative)
            elif num > 0:
                self._add_game_gold(num, is_recharge)

    #########################
    # 日志操作
    #########################

    #########################
    # 元宝操作
    #########################
    def _add_game_gold(self, add_num, is_recharge=False):
        """
        增加元宝
        :param add_num:元宝增加的数值
        :param is_recharge: 是否充值所得元宝
        :return:
        """
        assert add_num > 0
        self._dynamic_data.game_gold += add_num

        if is_recharge:
            self._dynamic_data.recharge_game_gold += add_num

    def _reduce_game_gold(self, cost_num, negative=False):
        """
        扣除元宝
        :param cost_num:元宝消耗的数值
        :param negative: 是否支持负数
        :return:
        """

        assert cost_num > 0
        self._dynamic_data.recharge_game_gold -= cost_num
        self._dynamic_data.game_gold -= cost_num

        if not negative and self._dynamic_data.game_gold < 0:
            raise ResourcesError('invalid game_gold: {0}'.format(self._dynamic_data.game_gold))

        if self._dynamic_data.recharge_game_gold < 0:
            self._need_reduce_free_gamegold = abs(self._dynamic_data.recharge_game_gold)
            self._dynamic_data.recharge_game_gold = 0

    #########################
    # 日志操作
    #########################
    def _log_normal_res(self, old_value, new_value, r_type, scene, remark, reserve):
        """
        记录非元宝资源的改动日志
        :param r_type: 资源类型
        :param old_value: 旧值
        :param new_value: 新值
        :param scene: 场景
        :param remark: 说明
        """
        from pyshare.framework.logproxy.non_core_log_proxy import NonCoreLogProxy

        # 资源字段名称
        field_name = self.get_res_name_by_type(r_type)
        if not scene:
            scene = '11202等'

        NonCoreLogProxy.vary(
            role_id=self._dynamic_data.role_guid,
            field_name=field_name,
            old_val=old_value,
            new_val=new_value,
            scene=scene,
            reserve=reserve,
            remark=remark)

    def _log_game_gold(self, old_value, new_value, is_recharge=False, lifetime=0, scene='Unknown',
                       remark='更新角色元宝值', reserve='{}', cp_order_id=""):
        """
        记录元宝日志

        关键数值日志表VariableLog中与元宝相关的FieldName有两个：
        - free_gold 赠送元宝
        - pay_gold 充值元宝

        保存资源的字段意义：
        - GameGold表示总元宝数(=充值元宝+赠送元宝)
        - RechargeGameGold表示充值元宝数

        元宝改动操作：
        - 充值
          - 总元宝+, 充值元宝+
          - 记录充值元宝+
        - 使用元宝道具
          - 总元宝+
          - 记录赠送元宝+
        - 使用元宝
          - 总元宝-, 充值元宝-
          - 记录充值元宝-; 若充值元宝扣完后小于0, 将负数绝对值记录为总元宝-, 充值元宝重置为0

        :param is_recharge: 是否操作充值元宝（仅当元宝增加时有用，元宝减少）
         :param lifetime: 生命周期∈[0,30]
         :param scene: 场景
         :param remark: 备注
         :param cp_order_id: 订单编号
        """
        # 元宝增加
        if new_value > old_value:
            # 充值元宝和赠送元宝的OldValue和NewValue要重新计算
            field_name = pay_gold_log_field_name if is_recharge else free_gold_log_field_name
            old_gold_value = old_value - self._init_recharge_game_gold \
                if field_name is free_gold_log_field_name else self._init_recharge_game_gold
            add_value = new_value - old_value
            GameLogProxy.coin(
                role_id=self._dynamic_data.role_guid,
                field_name=field_name,
                old_val=old_gold_value,
                new_val=old_gold_value + add_value,
                lifetime=0,
                scene=scene,
                remark=remark,
                reserve=reserve,
                cp_order_id=cp_order_id
            )

        # 元宝消耗
        elif new_value < old_value:
            # 消耗的元宝值
            cost_value = old_value - new_value
            # 是否需要消耗赠送元宝
            need_cost_free_gamegold = True if self._init_recharge_game_gold < cost_value else False
            if self._init_recharge_game_gold > 0:
                # 优先消耗充值元宝
                GameLogProxy.coin(
                    role_id=self._dynamic_data.role_guid,
                    field_name=pay_gold_log_field_name,
                    old_val=self._init_recharge_game_gold,  # 充值元宝的旧值
                    new_val=max(self._init_recharge_game_gold - cost_value, 0),
                    lifetime=lifetime,
                    scene=scene,
                    remark=remark,
                    reserve=reserve)

            # 可能要消耗赠送元宝
            if need_cost_free_gamegold:
                # 此时的abs(recharge_game_gold)表示赠送元宝需要记录的扣除数
                # 此处需增加写入赠送元宝变化的variable日志
                GameLogProxy.coin(
                    role_id=self._dynamic_data.role_guid,
                    field_name=free_gold_log_field_name,
                    old_val=self._init_game_gold - self._init_recharge_game_gold, # 赠送元宝的旧值
                    new_val=new_value, # 当需要消耗赠送元宝的时候，说明充值元宝已经全部用完了，所以GameGold=FreeGameGold
                    lifetime=lifetime,
                    scene=scene,
                    remark=remark,
                    reserve=reserve)

    #########################
    # 其他
    #########################
    def _log_res_change(self, r_type, old_value, scene, remark, is_recharge, reserve, cp_order_id):
        """

        :return:
        """
        # 记录日志
        new_value = self.get_res_by_type(r_type)
        # 普通资源：银粮兵,悟性值
        if r_type in (ItemType.Food, ItemType.Soldier, ItemType.Silver, ItemType.Perception,
                      ItemType.EquipmentStuffNormal, ItemType.EquipmentStuffAdvance):
            self._log_normal_res(old_value, new_value, r_type=r_type, scene=scene, remark=remark, reserve=reserve)
        # 元宝
        elif r_type == ItemType.GameGold:
            self._log_game_gold(old_value=old_value,
                                new_value=new_value,
                                scene=scene,
                                remark=remark,
                                is_recharge=is_recharge,
                                reserve=reserve,
                                cp_order_id=cp_order_id)

            self._reset()

    def update_resource_by_type_and_log(self, r_type, num, scene='Unknown', remark='更新角色资源值', is_recharge=False,
                                        reserve='{}', is_trigger_event=True, negative=False, cp_order_id=""):
        """
        更新资源并记录日志

        res_utils.py唯一对外开放的修改方法
        :param r_type: 资源类型
        :param num: 资源修改的delta值
        :param scene: 场景，基本上是接口号
        :param remark: 说明
        :param is_recharge: 仅对元宝资源有用：当该值为真，则表示为充值操作
        :param reserve: 日志变换值（扩展字段）
        :param is_trigger_event: 是否触发活动事件
        :param negative: 是否可以支持负数
        :param cp_order_id: 订单ID（真实充值时才需传入）
        """
        assert r_type in res_type_name_mapping

        old_value = self.get_res_by_type(r_type)

        with RoleLock.lock(self._dynamic_data.role_guid):
            self._update_resource_by_type(r_type, num, is_recharge=is_recharge, negative=negative)
            ResourcesRepository.save(self._dynamic_data)

        # 触发活动事件
        if is_trigger_event and num < 0 and r_type in res_type_to_activity_type:
            event = events.ActivityProgressChanged(
                role_id=self._dynamic_data.RoleGuid,
                a_type=res_type_to_activity_type[r_type],
                add_value=-num)
            zope.component.handle(event)
        # 更新使用资源记录上下文
        from pyshare.core.context import action_context_storage
        progress_list = action_context_storage.ctx.progress_list
        progress_dict = {"IsTriggerEvent": is_trigger_event,
                         "Num": num,
                         "Type": r_type
                         }
        progress_list.append(progress_dict)
        action_context_storage.ctx.progress_list = progress_list

        self._log_res_change(r_type=r_type, old_value=old_value,
                             scene=str(scene), remark=remark, is_recharge=is_recharge, reserve=reserve, cp_order_id=cp_order_id)

    def update_event(self, r_type, num):
        """
        触发资源对应事件
        :param r_type: 道具类型
        :param num: 数目(正值)
        :return:
        """
        event = events.ActivityProgressChanged(
            role_id=self._dynamic_data.RoleGuid,
            a_type=res_type_to_activity_type[r_type],
            add_value=num)
        zope.component.handle(event)

    def _reset(self):
        """
        重置控制参数
        :return:
        """
        self._need_reduce_free_gamegold = 0
        self._init_game_gold = self._dynamic_data.game_gold
        self._init_recharge_game_gold = self._get_recharge_gamegold()


def log_when_buy_month_card_and_year_card(rid, amount, product_id, cur_pay_gold, cp_order_id):
    """
    购买月卡/年卡时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param product_id: 产品编号
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    from pyshare.const.enums.payment import RechargeType

    remark = ''
    lifetime = 0
    gain_game_gold = amount * 10
    if product_id == RechargeType.MonthPlan:
        remark = '购买月卡'
        lifetime = 30
    elif product_id == RechargeType.YearPlan:
        remark = '购买年卡'
        lifetime = 365

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene='90102',
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买月卡/年卡
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=lifetime,
        scene='90102',
        remark=remark)


def log_when_buy_growth_plan(rid, amount, plan_type, plan_id, cur_pay_gold, lifetime, cp_order_id):
    """
    购买成长计划时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param plan_type: 计划类型
    :param plan_id: 计划id
    :param cur_pay_gold: 当前充值元宝数
    :param lifetime: 产品周期
    :param cp_order_id: 订单编号
    :return:
    """
    remark = '购买成长计划'
    gain_game_gold = amount * 10
    scene = str(plan_type) + ':' + str(plan_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买成长计划
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=lifetime,
        scene=scene,
        remark=remark)


def log_when_buy_cash_gift(rid, amount, cash_gift_id, cur_pay_gold, cp_order_id):
    """
    购买现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param cash_gift_id: 现金礼包id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(cash_gift_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买现金礼包')


def log_when_buy_unlock_recharge(rid, amount, unlock_id, cur_pay_gold, cp_order_id):
    """
    购买充值解锁,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param unlock_id: 解锁id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(unlock_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买充值解锁
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='充值解锁')


def log_when_buy_fund(rid, amount, fund_type, fund_id, cur_pay_gold, cp_order_id):
    """
    购买基金时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param fund_type: 基金类型
    :param fund_id: 基金id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    from pyshare.framework.logproxy.log_proxy import GameLogProxy

    remark = '购买基金'
    gain_game_gold = amount * 10
    scene = str(fund_type) + ':' + str(fund_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买国力基金
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_cash_time_limit_gift(rid, amount, cash_time_limit_id, cur_pay_gold, cp_order_id):
    """
    购买限时现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param cash_time_limit_id: 限时现金礼包id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(cash_time_limit_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买限时现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买限时现金礼包')


def log_when_buy_new_growth_plan(rid, amount, plan_type, plan_version, plan_id, cur_pay_gold, lifetime, cp_order_id):
    """
    购买新成长计划时,需要增加的额外日志(数据中心统计对账所需)
    :param plan_version: 版本id
    :param rid:
    :param amount: 金额
    :param plan_type: 计划类型
    :param plan_id: 计划id
    :param cur_pay_gold: 当前充值元宝数
    :param lifetime: 产品周期
    :param cp_order_id: 订单编号
    :return:
    """
    remark = '购买新成长计划'
    gain_game_gold = amount * 10
    scene = str(plan_type) + ':' + str(plan_version) + ':' + str(plan_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买成长计划
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=lifetime,
        scene=scene,
        remark=remark)


def log_when_buy_limit_fund(rid, amount, fund_type, fund_id, cur_pay_gold, cp_order_id):
    """
    购买限时基金时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param fund_type: 基金类型
    :param fund_id: 基金id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    if int(fund_type) == LimitFundType.EmperorFund:
        remark = '购买限时清帝基金'
    else:
        remark = '购买限时清妃基金'
    gain_game_gold = amount * 10
    scene = str(fund_type) + ':' + str(fund_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买限时清帝清妃基金
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_regress_limit_gift(rid, amount, limit_gift_id, cur_pay_gold, cp_order_id):
    """
    购买玩家回归限时礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param limit_gift_id: 限时礼包id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(limit_gift_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买玩家回归限时礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买玩家回归限时礼包')


def log_when_buy_regress_cash_gift(rid, amount, cash_gift_id, cur_pay_gold, cp_order_id):
    """
    购买玩家回归现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param cash_gift_id: 现金礼包id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(cash_gift_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买玩家回归现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买玩家回归现金礼包')


def log_when_buy_island_cash_gift(rid, amount, activity_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买蓬莱仙岛现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount:
    :param activity_id:
    :param gift_id:
    :param cur_pay_gold:
    :param cp_order_id:
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(gift_id)
    reserve = {'ActivityId': activity_id}

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id,
        reserve=reserve
    )

    # 2.充值元宝购买玩家回归现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买蓬莱仙岛现金礼包',
        reserve=reserve
    )


def log_when_buy_activity_cash_gift(rid, amount, cash_gift_id, cur_pay_gold, cp_order_id):
    """
    购买活动现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param cash_gift_id: 现金礼包id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(cash_gift_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买玩家回归现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买活动现金礼包')


def log_when_buy_optional_award_cash_gift(rid, amount, pool_id, cur_pay_gold, cp_order_id):
    """
    购买自选奖励现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param pool_id: 现金礼包id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(pool_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买玩家回归现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买自选奖励现金礼包')


def log_when_buy_monopoly_invest_cash_gift(rid, amount, template_id, cur_pay_gold, cp_order_id):
    """
    购买大富翁投资礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param template_id:
    :param rid:
    :param amount: 金额
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    remark = '购买大富翁投资现金礼包'
    gain_game_gold = amount * 10
    scene = str(template_id)

    # 1.人民币购买大富翁投资现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买大富翁投资现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_monopoly_gift_grid_cash_gift(rid, amount, template_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买大富翁礼包格现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param gift_id:
    :param template_id:
    :param rid:
    :param amount: 金额
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    remark = '购买大富翁礼包格现金礼包'
    gain_game_gold = amount * 10
    scene = str(template_id) + ':' + str(gift_id)

    # 1.人民币购买大富翁礼包格现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买大富翁礼包格现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_festival_cash_gift(rid, amount, activity_id, cur_pay_gold, cp_order_id):
    """
    购买节日现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param activity_id: 活动id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(activity_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买节日现金礼包')


def log_when_buy_siegelord_cash_gift(rid, amount, field_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买攻城掠地现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount:
    :param field_id:
    :param gift_id:
    :param cur_pay_gold:
    :param cp_order_id:
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(gift_id)
    reserve = {'FieldId': field_id}

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id,
        reserve=reserve
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买攻城略地现金礼包',
        reserve=reserve
    )


def log_when_buy_siegelord_limit_cash_gift(rid, amount, field_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买攻城掠地限时现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount:
    :param field_id:
    :param gift_id:
    :param cur_pay_gold:
    :param cp_order_id:
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(gift_id)
    reserve = {'FieldId': field_id}

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买限时现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买攻城略地限时现金礼包',
        reserve=reserve
    )


def log_when_buy_celadon_allies_gift(rid, amount, template_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买青瓷御器全盟礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param gift_id:
    :param template_id:
    :param rid:
    :param amount: 金额
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    remark = '购买青瓷御器全盟礼包'
    gain_game_gold = amount * 10
    scene = str(template_id) + ':' + str(gift_id)

    # 1.人民币购买青瓷御器全盟礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买青瓷御器全盟礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_fight_cash_gift(rid, amount, fight_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买皇决之选--现金礼包(高级商城)时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount:
    :param fight_id:
    :param gift_id:
    :param cur_pay_gold:
    :param cp_order_id:
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(gift_id)
    reserve = {'FightId': fight_id}

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id,
        reserve=reserve
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买皇决之选现金礼包',
        reserve=reserve
    )


def log_when_buy_push_gift(rid, amount, activity_id, cur_pay_gold, cp_order_id):
    """
    购买推送礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param activity_id: 活动id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(activity_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买推送礼包')


def log_when_buy_vip_limit_gift(rid, amount, gift_id, cur_pay_gold, cp_order_id):
    """
    购买vip限购礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount:
    :param gift_id:
    :param cur_pay_gold:
    :param cp_order_id:
    :return:
    """
    remark = '购买vip限购礼包'
    gain_game_gold = amount * 10
    scene = str(gift_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买vip限购礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_minister_fund(rid, amount, activity_id, cur_pay_gold, cp_order_id):
    """
    购买名臣基金时,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount:
    :param activity_id:
    :param cur_pay_gold:
    :param cp_order_id:
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(activity_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id,
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买名臣基金',
    )


def log_when_buy_tower_limit_cash_gift(rid, amount, template_id, gift_id, cur_pay_gold, cp_order_id):
    """
    购买爬塔触发现金礼包时,需要增加的额外日志(数据中心统计对账所需)
    :param gift_id:
    :param template_id:
    :param rid:
    :param amount: 金额
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    remark = '购买爬塔触发现金礼包'
    gain_game_gold = amount * 10
    scene = str(template_id) + ':' + str(gift_id)

    # 1.人民币购买爬塔触发现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买爬塔触发现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark=remark)


def log_when_buy_cross_fish_cash_gift(rid, amount, activity_id, cur_pay_gold, cp_order_id):
    """
    购买御海垂纶现金礼包,需要增加的额外日志(数据中心统计对账所需)
    :param rid:
    :param amount: 金额
    :param activity_id: 活动id
    :param cur_pay_gold: 当前充值元宝数
    :param cp_order_id: 订单编号
    :return:
    """
    gain_game_gold = amount * 10
    scene = str(activity_id)

    # 1.人民币购买充值元宝
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold,
        new_val=cur_pay_gold + gain_game_gold,
        lifetime=0,
        scene=scene,
        remark='充值获得',
        cp_order_id=cp_order_id
    )

    # 2.充值元宝购买现金礼包
    GameLogProxy.coin(
        role_id=rid,
        field_name=pay_gold_log_field_name,
        old_val=cur_pay_gold + gain_game_gold,
        new_val=cur_pay_gold,
        lifetime=0,
        scene=scene,
        remark='购买御海垂纶现金礼包')


if __name__ == '__main__':

    dummp_save = lambda x: None
    # ResManager.save = dummp_save
    resource = ResourcesRepository.query_all()[0]
    print resource.role_guid
    print resource.asdict()

    res_manager = ResManager(resource)

    # fg=0, rg=0

    # fg=100, rg=0
    # free_gold, 0, 100
    res_manager.update_resource_by_type_and_log(ItemType.GameGold, 100, remark='1')
     # fg=100, rg=100
    # pay_gold, 0, 100
    res_manager.update_resource_by_type_and_log(ItemType.GameGold, 100, is_recharge=True, remark='2')
     # fg=100, rg=200
    # pay_gold, 100, 200
    res_manager.update_resource_by_type_and_log(ItemType.GameGold, 100, is_recharge=True, remark='3')
     # fg=100, rg=50
    # pay_gold, 200, 50
    res_manager.update_resource_by_type_and_log(ItemType.GameGold, -150, remark='4')
     # fg=150, rg=50
    # free_gold, 100, 150
    res_manager.update_resource_by_type_and_log(ItemType.GameGold, 50, remark='5')
      # fg=100, rg=0
    # pay_gold, 50, 0
    # free_gold, 150, 100
    res_manager.update_resource_by_type_and_log(ItemType.GameGold, -100, remark='6')
